package com.iweb.netty;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.iweb.common.result.ResultEntity;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用来处理用户上线后主动获取通知
 */
@Component
public class NoticeWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    // 保存webSocket的用户连接
    public static ConcurrentHashMap<String, Channel> userChannelMap = new ConcurrentHashMap<>();

    // 用来保存用户对应的队列
    public static ConcurrentHashMap<String, String> queueMap = new ConcurrentHashMap<>();

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Resource(name = "sysNoticeContainer")
    private SimpleMessageListenerContainer sysNoticeContainer;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("监听建立连接");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        System.out.println("监听数据...");
        // 约定用户第一次请求需要携带用户ID
        // 获取用户请求数据
        String text = msg.text();
        // 获取用户id
        String userId = JSON.parseObject(text).get("userId").toString();
        // 建立 webSocket 连接
        Channel channel = userChannelMap.get(userId);
        if (channel == null) {
            channel = ctx.channel();
            userChannelMap.put(userId, channel);
        }
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate);
        // 只用完成新消息的提醒即可，只需要获取消息的数量
        // 文章订阅类通知
        sysNotice(userId, channel, rabbitAdmin);

        // 点赞类通知
    }

    // 文章订阅类通知
    private void sysNotice(String userId, Channel channel, RabbitAdmin rabbitAdmin) {
        /*系统通知消息推送-开始*/
        // 生成队列名称
        String queueName = "article_subscribe_" + userId;
        // 判断队列是否存在
        // 获取Rabbit的Properties容器
        Properties queueProperties = rabbitAdmin.getQueueProperties(queueName);
        // 获取消息数量
        int sysNoticeCount = 0;
        if (queueProperties != null) {
            sysNoticeCount = Convert.toInt(queueProperties.get("QUEUE_MESSAGE_COUNT"));
            queueMap.put(channel.id().asLongText(), queueName);
        }
        // 封装返回数据
        Map<String, Integer> resultMap = new HashMap<>();
        resultMap.put("sysNoticeCount", sysNoticeCount);

        ResultEntity<Map<String, Integer>> response =
                ResultEntity.CUSTOM(2000, "消费成功", true, resultMap);
        // 发送数据给用户
        channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(response)));
        // 清空消息
        if (sysNoticeCount > 0) {
            rabbitAdmin.purgeQueue(queueName);
        }

        // 注册监听消息
        if (queueProperties != null) {
            sysNoticeContainer.addQueueNames(queueName);
        }
        /*系统通知消息推送-结束*/
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("监听断开连接");
        String id = ctx.channel().id().asLongText();
        String queueName = queueMap.get(id);
        if (queueName != null) {
            sysNoticeContainer.removeQueueNames(queueName);
        }
    }
}
